﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AtomicTypes;
using NDimArrayNamespace;

namespace QLabValues
{
    public class QFloat64NDimArray : NDimArray<AtomicTypes.QFloat64>, IQLabValue, IIsComplex
    {
        public QFloat64NDimArray()
            : base()
        {
        }
        public QFloat64NDimArray(params int[] dimensionSize)
            : base(dimensionSize)
        {
        }
        public QFloat64NDimArray(QFloat64[] data, params int[] dimensionSize)
            : base(data, dimensionSize)
        {
        }

        //Darko dodao
        public QFloat64NDimArray(QBooleanNDimArray qba)
        {
            QFloat64[] els = new QFloat64[qba.Data.Count()];
            for (int i = 0; i < qba.Data.Count(); i++)
                els[i] = new QFloat64(qba.Data[i]);
            this.Data = (QFloat64[])els.Clone();
            this.DimensionSize = (int[])qba.DimensionSize.Clone();
        }

        //Darko dodao
        public QFloat64NDimArray(QCharNDimArray qca)
        {
            QFloat64[] els = new QFloat64[qca.Data.Count()];
            for (int i = 0; i < qca.Data.Count(); i++)
                els[i] = new QFloat64(qca.Data[i]);
            this.Data = (QFloat64[])els.Clone();
            this.DimensionSize = (int[])qca.DimensionSize.Clone();
        }

        //Darko dodao
        public QFloat64NDimArray(QUInt64NDimArray qia)
        {
            QFloat64[] els = new QFloat64[qia.Data.Count()];
            for (int i = 0; i < qia.Data.Count(); i++)
                els[i] = new QFloat64(qia.Data[i]);
            this.Data = (QFloat64[])els.Clone();
            this.DimensionSize = (int[])qia.DimensionSize.Clone();
        }

        //Darko dodao
        public QFloat64NDimArray(QInt64NDimArray qia)
        {
            QFloat64[] els = new QFloat64[qia.Data.Count()];
            for (int i = 0; i < qia.Data.Count(); i++)
                els[i] = new QFloat64(qia.Data[i]);
            this.Data = (QFloat64[])els.Clone();
            this.DimensionSize = (int[])qia.DimensionSize.Clone();
        }

        //Darko dodao
        public QFloat64NDimArray(QFloat64NDimArray qfa)
            :base(qfa.Data, qfa.DimensionSize)
        {
        }

        public object Clone()
        {
            return (object)new QFloat64NDimArray(Data, DimensionSize);
        }

        public QFloat64NDimArray(QLabValues.IQLabValue iq)
        {
            if (iq.GetEnumType() == QLabValues.IQLabValueType.QBooleanNDimArray)
            {
                QBooleanNDimArray qba = new QBooleanNDimArray((QBooleanNDimArray)iq);
                QFloat64[] els = new QFloat64[qba.Data.Count()];
                for (int i = 0; i < qba.Data.Count(); i++)
                    els[i] = new QFloat64(qba.Data[i]);
                this.Data = (QFloat64[])els.Clone();
                this.DimensionSize = (int[])qba.DimensionSize.Clone();                
            }
            else if (iq.GetEnumType() == QLabValues.IQLabValueType.QCharNDimArray)
            {
                QCharNDimArray qca = new QCharNDimArray((QCharNDimArray)iq);
                QFloat64[] els = new QFloat64[qca.Data.Count()];
                for (int i = 0; i < qca.Data.Count(); i++)
                    els[i] = new QFloat64(qca.Data[i]);
                this.Data = (QFloat64[])els.Clone();
                this.DimensionSize = (int[])qca.DimensionSize.Clone();
            }
            else if (iq.GetEnumType() == QLabValues.IQLabValueType.QUInt64NDimArray)
            {
                QUInt64NDimArray qia = new QUInt64NDimArray((QUInt64NDimArray)iq);
                QFloat64[] els = new QFloat64[qia.Data.Count()];
                for (int i = 0; i < qia.Data.Count(); i++)
                    els[i] = new QFloat64(qia.Data[i]);
                this.Data = (QFloat64[])els.Clone();
                this.DimensionSize = (int[])qia.DimensionSize.Clone();
            }
            else if (iq.GetEnumType() == QLabValues.IQLabValueType.QInt64NDimArray)
            {
                QInt64NDimArray qia = new QInt64NDimArray((QInt64NDimArray)iq);
                QFloat64[] els = new QFloat64[qia.Data.Count()];
                for (int i = 0; i < qia.Data.Count(); i++)
                    els[i] = new QFloat64(qia.Data[i]);
                this.Data = (QFloat64[])els.Clone();
                this.DimensionSize = (int[])qia.DimensionSize.Clone();
            }
            else if (iq.GetEnumType() == QLabValues.IQLabValueType.QFloat64NDimArray)
            {
                QFloat64NDimArray qfa = new QFloat64NDimArray((QFloat64NDimArray)iq);
                QFloat64[] els = new QFloat64[qfa.Data.Count()];
                for (int i = 0; i < qfa.Data.Count(); i++)
                    els[i] = new QFloat64(qfa.Data[i]);
                this.Data = (QFloat64[])els.Clone();
                this.DimensionSize = (int[])qfa.DimensionSize.Clone();
            }
            else
            {
                //do ovog slucaja verovatno nikad nece doci zato sto ce pri koriscenju ovog konstruktora
                //u NumericalCalculations projectu, uvek pre njegovog pozivanja biti pozvana funkcija
                //canConvertListToEnum koja ce proveravati da li dobijeni IQlabValue moze da se konvertuje u ovaj tip
                //i ukoliko ona vrati true, tada ce se konstruktor pozvati
                throw (new Exception("Cannot convert this type to QFloat64Array."));
            }
        }

        public int[] ToIndexArray()
        {
            List<int> temp = new List<int>();
            for (int i = 0; i < this.Data.Count(); i++)
                temp.Add(Convert.ToInt32(Data[i].Real) - 1);
            return temp.ToArray();
        }

        public QFloat64NDimArray GetSubArray(int[][] subNDimArrayCoordinates)
        {
            NDimArray<QFloat64> tempArray = base.GetSubNDimArray(subNDimArrayCoordinates);
            return new QFloat64NDimArray(tempArray.Data, tempArray.DimensionSize);
        }

        public QFloat64NDimArray SubAssignment(QFloat64NDimArray matrix, int[][] subNDimArrayCoordinates)
        {
            NDimArray<QFloat64> tempArray = base.SubscriptedAssignment(new NDimArray<QFloat64>(matrix.Data, matrix.DimensionSize), subNDimArrayCoordinates);
            return new QFloat64NDimArray(tempArray.Data, tempArray.DimensionSize);
        }

        public QLabValues.IQLabValueType GetEnumType()
        {
            return QLabValues.IQLabValueType.QFloat64NDimArray;
        }

        public bool LogicalValue()
        {
            for (int i = 0; i < Data.Count(); i++)
                if (Data[i].Real == 0)
                    return false;
            return true;
        }
    }
}
